package com.dkts.oil.test.road;

import org.geotools.data.collection.ListFeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geojson.feature.FeatureJSON;
import org.locationtech.jts.geom.*;
import org.locationtech.jts.linearref.LengthIndexedLine;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;

import java.io.FileReader;
import java.io.FileWriter;
import java.util.*;

public class ShippingRouteGenerator {

    static class PortWithIndex {
        Point point;
        double index;
        Coordinate foot;

        public PortWithIndex(Point point, double index, Coordinate foot) {
            this.point = point;
            this.index = index;
            this.foot = foot;
        }
    }

    public static void main(String[] args) throws Exception {
        FeatureJSON fjson = new FeatureJSON();

        // 读取中心线
        FeatureIterator<SimpleFeature> lineIt = fjson.readFeatureCollection(new FileReader("src/main/resources/珠江.geojson")).features();
        Geometry centerGeom = null;
        if (lineIt.hasNext()) {
            centerGeom = (Geometry) lineIt.next().getDefaultGeometry();
        }
        lineIt.close();

        GeometryFactory gf = new GeometryFactory();
        LineString centerLine;

        if (centerGeom instanceof MultiLineString) {
            List<Coordinate> coords = new ArrayList<>();
            MultiLineString mls = (MultiLineString) centerGeom;
            for (int i = 0; i < mls.getNumGeometries(); i++) {
                LineString ls = (LineString) mls.getGeometryN(i);
                Collections.addAll(coords, ls.getCoordinates());
            }
            centerLine = gf.createLineString(coords.toArray(new Coordinate[0]));
        } else {
            centerLine = (LineString) centerGeom;
        }

        LengthIndexedLine indexedLine = new LengthIndexedLine(centerLine);

        // 读取港口点并投影
        FeatureIterator<SimpleFeature> portIt = fjson.readFeatureCollection(new FileReader("src/main/resources/珠江港口.geojson")).features();
        List<PortWithIndex> portsWithIndex = new ArrayList<>();
        while (portIt.hasNext()) {
            SimpleFeature feature = portIt.next();
            Point portPt = (Point) feature.getDefaultGeometry();
            double index = indexedLine.project(portPt.getCoordinate());
            Coordinate foot = indexedLine.extractPoint(index);
            portsWithIndex.add(new PortWithIndex(portPt, index, foot));
        }
        portIt.close();

        // 排序港口按航线索引
        portsWithIndex.sort(Comparator.comparingDouble(p -> p.index));

        // 串联完整路径：起点 -> 航线坐标 -> 垂足点 -> 港口点 -> 垂足点 -> 航线
        List<Coordinate> routeCoords = new ArrayList<>();
        Coordinate[] lineCoords = centerLine.getCoordinates();

        double currentIndex = 0;
        int portCursor = 0;

        for (int i = 0; i < lineCoords.length - 1; i++) {
            Coordinate c1 = lineCoords[i];
            double segStartIndex = indexedLine.project(c1);
            double segEndIndex = indexedLine.project(lineCoords[i + 1]);

            // 加入航线起点
            if (routeCoords.isEmpty()) {
                routeCoords.add(c1);
            }

            // 判断是否有港口投影点在当前线段内
            while (portCursor < portsWithIndex.size()) {
                PortWithIndex port = portsWithIndex.get(portCursor);
                if (port.index >= segStartIndex && port.index <= segEndIndex) {
                    // 插入垂足点
                    routeCoords.add(port.foot);
                    // 插入港口点
                    routeCoords.add(port.point.getCoordinate());
                    // 返回垂足点
                    routeCoords.add(port.foot);
                    portCursor++;
                } else {
                    break;
                }
            }

            // 插入航线下一个点
            routeCoords.add(lineCoords[i + 1]);
        }

        // 生成完整航线
        LineString finalRoute = gf.createLineString(routeCoords.toArray(new Coordinate[0]));

        // 输出 GeoJSON
        SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
        typeBuilder.setName("ShippingFullRoute");
        typeBuilder.add("geometry", LineString.class);
        SimpleFeatureType TYPE = typeBuilder.buildFeatureType();

        ListFeatureCollection featureCollection = new ListFeatureCollection(TYPE);
        SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);

        featureBuilder.add(finalRoute);
        featureCollection.add(featureBuilder.buildFeature(null));

        try (FileWriter writer = new FileWriter("src/main/resources/shipping_珠江_route.geojson")) {
            fjson.writeFeatureCollection(featureCollection, writer);
        }

        System.out.println("✔ 航线 → 垂足 → 港口 → 垂足 → 航线 路径生成完成，已保存 shipping_珠江_route.geojson");
    }
}
